package org.eiahe.hr.performance.listener;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.ehe.common.core.exception.ServiceException;
import org.ehe.common.core.utils.MapstructUtils;
import org.ehe.common.satoken.utils.LoginHelper;
import org.eiahe.hr.performance.domain.PerformanceLevel;
import org.eiahe.hr.performance.domain.PerformancePositionIndicator;
import org.eiahe.hr.performance.domain.PerformanceResult;
import org.eiahe.hr.performance.domain.PerformanceScore;
import org.eiahe.hr.performance.domain.PerformanceScoreDetail;
import org.eiahe.hr.performance.domain.bo.PerformancePushRecordBo;
import org.eiahe.hr.performance.domain.bo.PerformanceResultBo;
import org.eiahe.hr.performance.event.PerformanceScoredEvent;
import org.eiahe.hr.performance.event.PerformanceScoreDetailUpdatedEvent;
import org.eiahe.hr.performance.mapper.PerformanceLevelMapper;
import org.eiahe.hr.performance.mapper.PerformancePositionIndicatorMapper;
import org.eiahe.hr.performance.mapper.PerformanceResultMapper;
import org.eiahe.hr.performance.mapper.PerformanceScoreMapper;
import org.eiahe.hr.performance.mapper.PerformanceScoreDetailMapper;
import org.eiahe.hr.performance.service.IPerformancePushRecordService;
import org.eiahe.hr.performance.service.IPerformanceResultService;
import org.eiahe.hr.performance.service.IPerformancePositionIndicatorService;
import org.eiahe.hr.performance.service.impl.PerformanceResultServiceImpl;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 绩效评分事件监听器
 *
 * @author :zhangnn
 * @className :PerformanceScoredEventListener
 * @description: TODO
 * @date 2025-11-21 09:47:25
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class PerformanceScoredEventListener {
    private final IPerformanceResultService resultService;
    private final PerformanceResultMapper resultMapper;
    private final PerformanceLevelMapper levelMapper;
    private final IPerformancePushRecordService pushRecordService;
    private final PerformanceScoreMapper scoreMapper;
    private final PerformancePositionIndicatorMapper positionIndicatorMapper;
    private final PerformanceScoreDetailMapper scoreDetailMapper;
    private final IPerformancePositionIndicatorService positionIndicatorService;

    @Async // 异步执行，不影响评分响应速度
    @EventListener
    @Transactional(rollbackFor = Exception.class)
    public void handlePerformanceScored(PerformanceScoredEvent event) {
        try {
            String employeeNo = event.getEmployeeNo();
            Long cycleId = event.getScoreBo().getCycleId();
            Long indicatorId = event.getIndicatorId();

            // Step 3: 更新或创建绩效结果
            PerformanceResultBo resultBo = PerformanceResultBo.builder()
                    .employeeNo(employeeNo)
                    .cycleId(cycleId)
                    .totalScore(BigDecimal.ZERO)
                    .levelId(null)
                    .status("0") // 待确认状态
                    .build();

            // 直接调用queryByEmployeeAndCycle方法
            PerformanceResult existingResult = ((PerformanceResultServiceImpl) resultService)
                    .queryByEmployeeAndCycle(employeeNo, cycleId);

            Long resultId;
            if (existingResult != null) {
                resultBo.setResultId(existingResult.getResultId());
                // Step 1: 计算总得分
                BigDecimal totalScore = calculateTotalScore(existingResult.getResultId());
                // Step 2: 评定绩效等级
                Long levelId = evaluatePerformanceLevel(totalScore);
                resultBo.setLevelId(levelId);
                resultBo.setTotalScore(totalScore);
                resultService.updateByBo(resultBo);
                resultId = existingResult.getResultId();
            } else {
                PerformanceResult resultEntity = MapstructUtils.convert(resultBo, PerformanceResult.class);
                resultEntity.setCreateBy(LoginHelper.getUserId());
                resultEntity.setTenantId(LoginHelper.getTenantId());
                boolean success = resultMapper.insert(resultEntity) > 0;
                if (success) {
                    resultId = resultEntity.getResultId();
                    resultBo.setResultId(resultId);
                } else {
                    throw new ServiceException("创建绩效结果失败");
                }
            }

            // 生成推送记录
            generatePushRecord(employeeNo, resultBo);

            // 生成绩效评分明细
            generateScoreDetails(employeeNo, cycleId, resultId);

            log.info("绩效评分闭环处理完成: employeeNo={}", employeeNo);

        } catch (Exception e) {
            log.error("绩效评分闭环处理失败", e);
            throw new ServiceException("自动计算绩效结果失败: " + e.getMessage());
        }
    }

    @Async // 异步执行，不影响评分响应速度
    @EventListener
    @Transactional(rollbackFor = Exception.class)
    public void handlePerformanceScoreDetailUpdated(PerformanceScoreDetailUpdatedEvent event) {
        try {
            Long detailId = event.getDetailId();
            Long resultId = event.getResultId();

            // 获取绩效结果记录
            PerformanceResult result = resultMapper.selectById(resultId);
            if (result != null) {
                Long cycleId = result.getCycleId();
                String employeeNo = result.getEmployeeNo();

                // 重新计算总得分
                BigDecimal totalScore = calculateTotalScore(resultId);

                // 重新评定绩效等级
                Long levelId = evaluatePerformanceLevel(totalScore);

                // 更新绩效结果
                PerformanceResultBo resultBo = PerformanceResultBo.builder()
                        .resultId(resultId)
                        .employeeNo(employeeNo)
                        .cycleId(cycleId)
                        .totalScore(totalScore)
                        .levelId(levelId)
                        .status("0") // 待确认状态
                        .build();

                resultService.updateByBo(resultBo);

                log.info("绩效评分明细更新处理完成: employeeNo={}, detailId={}, totalScore={}, levelId={}",
                        employeeNo, detailId, totalScore, levelId);
            }
        } catch (Exception e) {
            log.error("绩效评分明细更新处理失败", e);
            throw new ServiceException("自动计算绩效结果失败: " + e.getMessage());
        }
    }

    /**
     * 计算员工在考核周期的总得分
     */
    private BigDecimal calculateTotalScore(Long resultId) {
        // 2. 获取该绩效结果下的所有评分明细
        LambdaQueryWrapper<PerformanceScoreDetail> detailLqw = Wrappers.lambdaQuery();
        detailLqw.eq(PerformanceScoreDetail::getResultId, resultId);
        detailLqw.eq(PerformanceScoreDetail::getDelFlag, "0");
        List<PerformanceScoreDetail> details = scoreDetailMapper.selectList(detailLqw);

        if (CollUtil.isEmpty(details)) {
            return BigDecimal.ZERO;
        }

        // 3. 计算所有评分明细的加权得分总和
        BigDecimal totalScore = details.stream()
                .map(detail -> {
                    // 使用评分明细中的加权得分
                    return detail.getWeightedScore() != null ? detail.getWeightedScore() : BigDecimal.ZERO;
                })
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        return totalScore.setScale(2, RoundingMode.HALF_UP);
    }

    /**
     * 根据得分评定等级
     */
    private Long evaluatePerformanceLevel(BigDecimal score) {
        LambdaQueryWrapper<PerformanceLevel> lqw = Wrappers.lambdaQuery();
        lqw.le(PerformanceLevel::getMinScore, score); // 分数 >= 最低分（满足该等级的准入条件）
        lqw.eq(PerformanceLevel::getStatus, "0"); // 状态正常
        lqw.eq(PerformanceLevel::getDelFlag, "0"); // 未删除
        lqw.orderByDesc(PerformanceLevel::getSortOrder); // 优先级高的在前（比如S级sort_order=1，D级=0）
        lqw.last("LIMIT 1");
        List<PerformanceLevel> levels = levelMapper.selectList(lqw);
        return CollUtil.isNotEmpty(levels) ? levels.get(0).getLevelId() : null;
    }

    /**
     * 生成推送记录
     */
    private void generatePushRecord(String employeeNo, PerformanceResultBo resultBo) {
        // 确保resultId不为空
        if (resultBo.getResultId() == null) {
            log.warn("绩效结果ID为空，无法生成推送记录: employeeNo={}", employeeNo);
            return;
        }

        PerformancePushRecordBo pushBo = new PerformancePushRecordBo();
        pushBo.setEmployeeNo(employeeNo);
        pushBo.setResultId(resultBo.getResultId());
        pushBo.setPushTime(new Date());
        pushBo.setPushStatus("1"); // 已推送
        pushBo.setReadStatus("0"); // 未读

        pushRecordService.insertByBo(pushBo);
    }

    /**
     * 生成绩效评分明细
     */
    public void generateScoreDetails(String employeeNo, Long cycleId, Long resultId) {
        // 1. 获取该员工在指定周期的所有评分明细
        LambdaQueryWrapper<PerformanceScore> scoreLqw = Wrappers.lambdaQuery();
        scoreLqw.eq(PerformanceScore::getEmployeeNo, employeeNo);
        scoreLqw.eq(PerformanceScore::getCycleId, cycleId);
        scoreLqw.eq(PerformanceScore::getDelFlag, "0");
        List<PerformanceScore> scores = scoreMapper.selectList(scoreLqw);

        if (CollUtil.isEmpty(scores)) {
            return;
        }
        // 3. 为每个评分记录创建评分明细
        for (PerformanceScore score : scores) {
            List<String> scorers = new ArrayList<>();
            if (score.getScorer() != null && !score.getScorer().isEmpty()) {
                scorers = Arrays.asList(score.getScorer().split(","));
            }
            for (String scorer : scorers) {
                // 查找是否已存在对应的评分明细记录
                LambdaQueryWrapper<PerformanceScoreDetail> lqw = Wrappers.lambdaQuery();
                lqw.eq(PerformanceScoreDetail::getResultId, resultId);
                lqw.eq(PerformanceScoreDetail::getIndicatorId, score.getIndicatorId());
                lqw.eq(PerformanceScoreDetail::getScorer, scorer);
                lqw.eq(PerformanceScoreDetail::getDelFlag, "0");

                PerformanceScoreDetail detail = scoreDetailMapper.selectOne(lqw);

                if (detail != null) {
                    // 更新现有记录
                    detail.setScore(score.getScore());
                    detail.setScoreStatus("1"); // 已评分
                    detail.setScoreId(score.getScoreId()); // 关联评分ID

                    scoreDetailMapper.updateById(detail);
                } else {
                    detail = new PerformanceScoreDetail();
                    // 创建新记录
                    detail.setScoreId(score.getScoreId());
                    detail.setResultId(resultId);
                    detail.setIndicatorId(score.getIndicatorId());
                    detail.setScorer(scorer);
                    detail.setScore(score.getScore());
                    detail.setCreateBy(LoginHelper.getUserId());
                    detail.setTenantId(LoginHelper.getTenantId());
                    // 获取指标权重并计算加权得分
                    BigDecimal weight = positionIndicatorService.getPositionIndicatorWeight(
                            score.getPositionId(), score.getIndicatorId());
                    detail.setWeight(weight);

                    // 计算加权得分
                    BigDecimal weightedScore = positionIndicatorService.calculateWeightedScore(
                            score.getScore(), weight);
                    detail.setWeightedScore(weightedScore);

                    scoreDetailMapper.insert(detail);
                }
            }
        }
    }
}
